package redis

import (
	"context"
	"github.com/redis/go-redis/v9"
	"github.com/spf13/cast"
	"go.uber.org/zap"
	"reward-server/global"
	"strings"
)

type IStatistics interface {
	Set(key, member string, score float64) (ok bool, err error)
	Get(key, member string) (score float64, err error)
	GetWithScores(key string, start, end int64) ([]redis.Z, error)
	SearchWithScores(key string, match string, limit int64) (map[string]int64, error)
}

type Statistics struct {
	//ShortplayId int64
	//TenantID    int64
	//Num         int64
}

func NewStatistics() IStatistics {

	return &Statistics{}
}

// Set 分数增加
func (p *Statistics) Set(key, member string, score float64) (ok bool, err error) {

	ctx := context.Background()

	//生成member

	exists, err := global.RedisDB.ZScore(ctx, key, member).Result() // 使用 ZRank 命令检测成员是否存在
	zap.S().Infof("是否存在此key:%+v,错误信息：%+v", exists, err)

	//如果成员不存在添加成员
	if exists == 0 {
		if err := global.RedisDB.ZAdd(ctx, key, redis.Z{Score: 1, Member: member}).Err(); err != nil {
			zap.S().Infof("添加新统计错误信息：%+v", exists, err)
			return false, err
		}
		return true, nil
	}
	//如果成员存在根据score 类型 增减 分数
	err = global.RedisDB.ZIncrBy(ctx, key, score, member).Err()
	if err != nil {
		zap.S().Infof("追加分数错误信息：%+v", exists, err)
		return false, nil
	}
	return true, nil
}

// Get 获取成员值
func (p *Statistics) Get(key, member string) (score float64, err error) {
	//生成member
	//memberName := fmt.Sprintf(member, p.TenantID, p.ShortplayId, p.Num)
	ctx := context.Background()
	s, err := global.RedisDB.ZScore(ctx, key, member).Result()
	if err != nil {
		return 0, err
	}
	zap.S().Infof("获取key:%+v,成员：%+v-值：%v", key, member, s)
	return s, nil

}

// GetWithScores 获取范围统计信息
func (p *Statistics) GetWithScores(key string, start, end int64) ([]redis.Z, error) {
	ctx := context.Background()
	rankings, err := global.RedisDB.ZRevRangeWithScores(ctx, key, start, end).Result()
	if err != nil {
		return nil, err
	}
	return rankings, err
}

// SearchWithScores 搜索有序集合指定条件的成员key
// key zSet的键
// match 要搜索成员键（如：123:*）
// limit 一次显示数量
func (p *Statistics) SearchWithScores(key string, match string, limit int64) (map[string]int64, error) {
	ctx := context.Background()
	scan := global.RedisDB.ZScan(ctx, key, 0, match, limit)
	iterator := scan.Iterator()
	var vMap = map[string]int64{}
	for iterator.Next(ctx) {
		k := strings.ReplaceAll(iterator.Val(), ":", "-")
		iterator.Next(ctx)
		v := iterator.Val()
		vMap[k] = cast.ToInt64(v)
	}

	return vMap, nil
}
